今天我們要開始使用 Flask-WTF 來做表單,我們要做的表單還不少,但我們每個都會實作。他的概念是用 class 的方式把表單寫起來,然後建立一個表單實體並傳入 render_template
讓 jinja 處理。
我們會加入一個新檔案 forms.py
,他會放在 app/
裡面。
我們先來引入一些跟 Flask-WTF 有關的東西。
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.fields.html5 import EmailField
from wtforms.validators import DataRequired, Length, EqualTo, Regexp
一開始我們先引入 FlaskForm
,他會是我們之後所有表單繼承的對象。接下來我們引入了好幾個 field,他們基本上就是對應到 HTML 的那些 input type。比較麻煩的是 EmailField
要從 wtforms.fields.html5
引入,之後也會用到一些其他的 field 要從這裡引入,最後我們引入了一些 validator,他們是用來驗證使用者輸入是否正確的,等等我們會一個一個看到。
首先來看看最簡單的登入表單,在這裡面我們只需要叫使用者輸入帳號、密碼,然後按下送出即可。在 Flask-WTF 裡面,這樣就是三個欄位。
class LoginForm(FlaskForm):
username = StringField(
"Username", validators=[DataRequired()], render_kw={"placeholder": "Username"}
)
password = PasswordField(
"Password", validators=[DataRequired()], render_kw={"placeholder": "Password"}
)
submit = SubmitField("Login")
我們定義了一個 LoginForm
,用來處理使用者的登入,接著如剛剛所說,他繼承了 FLaskForm。
他有三個欄位,分別是 username
、password
、submit
,這些名字並不會顯示在網頁上,但是我們在處理模板及抓表單資料的時候會用到。接下來我們會分開解釋他們及其參數。
username
,很明顯就是用來填使用者名稱的。他是一個 StringField
,就是放文字的欄位。而他的第一個參數是這個欄位的名字,後面在 jinja 那邊會用到,他在 HTML 是 label
的角色。validators
是規定這個欄位要遵守的規則,他是一個 list,Flask-WTF 會一一檢查,沒過就會視為無效,到時候在寫藍圖的時候會看到怎麼判斷。這邊使用的是 DataRequired
,對應到 HTML 就是 input 裡面的 required
。而他的確會在 HTML 的部份加上 required,但就算手動把它移掉,到後端他還是會檢查一次。最後是 render_kw
,基本上它就是一些額外的參數,像此處就是指定他的 placeholder
,這樣在 HTML 那邊就會顯示出 placeholder="Username"
,同理,如果想加入 id
,就可以在 render_kw
裡面加上 "id": "cat"
之類的東西。PasswordField
,也就是密碼欄位,所以它會自動在 HTML 變成 type="password"
。type="submit"
,而他會用 SubmitField
這個東西。他的第一個參數跟前兩個差不多,就是他的名字,但這個名字就會直接變成這個 submit 按鈕的文字,在 HTML 就是他的 value
。剛剛第一個表單蠻簡單的,就少少三個欄位,但接下來要寫的註冊帳號表單就沒這麼輕鬆了,先來看看程式碼吧。
class RegisterForm(FlaskForm):
username = StringField(
"Username",
validators=[
DataRequired(),
Length(min=4, max=30, message="The name should be 4 to 30 letters long."),
Regexp(
"[a-zA-Z0-9_]+",
message="Only letters, numbers and underscore are allowed in username.",
),
],
render_kw={"placeholder": "Username"},
)
password = PasswordField(
"Password",
validators=[
DataRequired(),
Length(min=6, message="The password must contain at least 6 characters."),
],
render_kw={"placeholder": "Password"},
)
repeat_password = PasswordField(
"Repeat Password",
validators=[
DataRequired(),
EqualTo("password", message="Passwords not match."),
],
render_kw={"placeholder": "Repeat Password"},
)
email = EmailField(
"Email", validators=[DataRequired()], render_kw={"placeholder": "Email"}
)
submit = SubmitField("Register")
其實這次也就只有五個欄位,但是每一個欄位都有一堆麻煩的設定,我們一個一個來看。
validators
加了不少東西。首先是剛剛就有的 DataRequired
,在此不再多說了。接下來是 Length
,它是用來限制長度的,max
和 min
分別代表上下限,後面的 message
是當這個條件不被滿足時所要跳出的訊息 (在 DataRequired
也可以指定 message
,在寫藍圖的時候我們會處理這個訊息並 flash
到前端。最後一個是 Regexp
,就是正規表示式 (regular expression) 的意思,在這邊我們限制這個使用者名稱只能由英文字母、數字、下底線組成,如同下面的 message
所寫。DataRequired
,同時也限制最短密碼要有六個字元,沒有上限。validators
我們加入了 EqualTo
,他的第一個參數是要跟哪一個 field 有相同的值,要放的是變數名稱,但用的是字串 ("password"
),而不是變數本身 (password
)。EmailField
。value
設成 Register
。Automatically setting the id HTML attribute of a form element in flask-wtforms
HTML input Tag